package org.apache.ocean;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.TimeUnit;

/**
 *
 * @author jasonr
 */
public class RefWaitNotNull<V> {
  private V object;
  private ReentrantLock lock = new ReentrantLock();
  private Condition notNullCondition = lock.newCondition();

  public RefWaitNotNull() {
  }

  public V getNoWait() {
    return object;
  }

  public void set(V object) {
    lock.lock();
    try {
      this.object = object;
      if (object != null) {
        notNullCondition.signalAll();
      }
    } finally {
      lock.unlock();
    }
  }

  public V get() throws InterruptedException {
    if (object != null) {
      return object;
    }
    lock.lock();
    try {
      notNullCondition.await();
      return object;
    } finally {
      lock.unlock();
    }
  }

  public V get(TimeoutState timeoutState) throws GeneralTimeoutException, InterruptedException {
    if (object != null) {
      return object;
    }
    lock.lock();
    try {
      notNullCondition.await(timeoutState.getTimeLeft(), TimeUnit.MILLISECONDS);
      if (object == null) throw new GeneralTimeoutException(timeoutState);
      return object;
    } finally {
      lock.unlock();
    }
  }
}
